﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using System.Text;
using System.Threading.Tasks;
using static FanMotionWink.FanUtils;

namespace FanMotionWink
{
    public class CurvePoint
    {
        public float X;
        public float Y;

        public float PropsX => X;
        public float PropsY => Y;

        public CurvePoint()
        {
        }

        public CurvePoint(float v1, float v2)
        {
            this.X = v1;
            this.Y = v2;
        }
        public CurvePoint(double v1, double v2)
        {
            this.X = (float)v1;
            this.Y = (float)v2;
        }

        //public Point Point => this.ToPoint();

        public override string ToString()
        {
            return $"[{X},{Y}]";
        }
    }








    public static class UserControlCurveExtUtil
    {
        public static Vector2 ToVec2(this CurvePoint p)
        {
            return new Vector2((float)p.X, (float)p.Y);
        }

        public static int FindNearestPointIdx(this List<CurvePoint> curvePoints, CurvePoint refancedPoint, float ApproachDistance)
        {
            return curvePoints.FindIndex(curPoint =>
            {
                var distFromMs = Vector2.Distance(refancedPoint.ToVec2(), curPoint.ToVec2());
                return distFromMs < ApproachDistance;
            });
        }

        public static CurvePoint? FindNearestPoint(this List<CurvePoint> curvePoints, CurvePoint refancedPoint, float ApproachDistance)
        {
            var idx = curvePoints.FindNearestPointIdx(refancedPoint, ApproachDistance);
            return idx < 0 ? null : curvePoints[idx];
        }

        // 根据 X 计算Y
        // 温度曲线
        public static float? CalcYPosWithX(this List<CurvePoint> curvePoints, float refancedPointX)
        {
            var copyed = curvePoints.Select(item => item).ToList();
            copyed.Sort((a, b) => (int)(a.X - b.X));

            if (copyed.Count < 2)
            {
                return null;
            }

            if (refancedPointX <= copyed[0].X)
            {
                return copyed[0].X;
            }
            if (refancedPointX >= copyed[copyed.Count - 1].X)
            {
                return copyed[copyed.Count - 1].X;
            }

            for (int i = 0; i < copyed.Count - 1; i++)
            {
                var a = copyed[i];
                var b = copyed[i + 1];
                bool inSegment = a.X <= refancedPointX && refancedPointX < b.X;
                if (!inSegment)
                {
                    continue;
                }

                // 计算出投影焦点
                var pop = CalculateIntersection(new Vector2(refancedPointX, 1000), new Vector2(refancedPointX, -1000), a.ToVec2(), b.ToVec2());
                var theY = pop != null ? pop.Value.Y : b.Y;
                var minY = Math.Min(a.Y, b.Y);
                var maxY = Math.Max(a.Y, b.Y);
                theY = Math.Clamp(theY, minY, maxY);
                return (float)theY;
            }

            return null;
        }


        static Vector2? CalculateIntersection(Vector2 A1, Vector2 A2, Vector2 B1, Vector2 B2)
        {
            // 计算线段1和线段2的方向向量
            Vector2 D1 = new Vector2(A2.X - A1.X, A2.Y - A1.Y);
            Vector2 D2 = new Vector2(B2.X - B1.X, B2.Y - B1.Y);

            // 计算参数t1和t2
            double t1 = CrossProduct(B1 - A1, D2) / CrossProduct(D1, D2);
            double t2 = CrossProduct(B1 - A1, D1) / CrossProduct(D1, D2);

            // 如果t1和t2的取值在[0, 1]之间，表示线段相交
            if (t1 >= 0 && t1 <= 1 && t2 >= 0 && t2 <= 1)
            {
                // 计算交点坐标
                double intersectionX = A1.X + t1 * D1.X;
                double intersectionY = A1.Y + t1 * D1.Y;
                return new Vector2((float)intersectionX, (float)intersectionY);
            }

            // 线段不相交
            return null;
        }

        static double CrossProduct(Vector2 p1, Vector2 p2)
        {
            return p1.X * p2.Y - p1.Y * p2.X;
        }
    }


}
